﻿namespace ClassyBlog.DataAccess
{
    using System;
    using System.Diagnostics;

    using DomainObjects;

    public class LazyPage : Page
    {
        private static readonly object syncLock = new object();

        private bool loading;
        private bool loaded;

        public LazyPage(IArticleLoader<Page> loader)
        {
            if (loader == null)
            {
                throw new ArgumentNullException("loader");
            }

            Loader = loader;
        }

        public override string Title
        {
            get
            {
                if (CanLoad && (base.Title == null))
                {
                    Load();
                }

                return base.Title;
            }

            [DebuggerStepThrough]
            set
            {
                base.Title = value;
            }
        }

        public override string MetaKeywords
        {
            get
            {
                if (CanLoad && (base.MetaKeywords == null))
                {
                    Load();
                }

                return base.MetaKeywords;
            }

            [DebuggerStepThrough]
            set
            {
                base.MetaKeywords = value;
            }
        }

        public override string MetaDescription
        {
            get
            {
                if (CanLoad && (base.MetaDescription == null))
                {
                    Load();
                }

                return base.MetaDescription;
            }

            [DebuggerStepThrough]
            set
            {
                base.MetaDescription = value;
            }
        }

        public override string Author
        {
            get
            {
                if (CanLoad && (base.Author == null))
                {
                    Load();
                }

                return base.Author;
            }

            [DebuggerStepThrough]
            set
            {
                base.Author = value;
            }
        }

        public override bool AllowComments
        {
            get
            {
                if (CanLoad && !base.AllowComments)
                {
                    Load();
                }

                return base.AllowComments;
            }

            [DebuggerStepThrough]
            set
            {
                base.AllowComments = value;
            }
        }

        public override string Body
        {
            get
            {
                if (CanLoad && (base.Body == null))
                {
                    Load();
                }

                return base.Body;
            }

            [DebuggerStepThrough]
            set
            {
                base.Body = value;
            }
        }

        protected IArticleLoader<Page> Loader { get; private set; }

        private bool CanLoad
        {
            [DebuggerStepThrough]
            get
            {
                return !loading && !loaded;
            }
        }

        private void Load()
        {
            if (loaded)
            {
                return;
            }

            lock (syncLock)
            {
                if (loaded)
                {
                    return;
                }

                loading = true;
                Loader.Load(this);
                loading = false;
                loaded = true;
            }
        }
    }
}